#include "CL_News_pool.h"

int CL_News_pool::CL_RSS_Quelle::parse_rss_20(newsmap& map, pugi::xml_document& rss_doc, pugi::xml_node& version)
{
    std::set<std::size_t> news_hashes;
    int zaehler = 0;
    for(pugi::xml_node channel=version.child("channel"); channel; channel=channel.next_sibling("channel"))
    {
        CL_channel struct_channel;
        struct_channel=CL_channel();
        /*
                struct_channel.image.url;
                struct_channel.image.titel;
                struct_channel.image.link;*/
        if(pugi::xml_node tmp_node=channel.child("title"))struct_channel.titel=tmp_node.child_value();
        if(pugi::xml_node tmp_node=channel.child("link"))struct_channel.url=tmp_node.child_value();
        if(pugi::xml_node tmp_node=channel.child("description"))struct_channel.description=tmp_node.child_value();
        if(pugi::xml_node tmp_node=channel.child("language"))struct_channel.language=tmp_node.child_value();
        if(pugi::xml_node tmp_node=channel.child("copyright"))struct_channel.copyright=tmp_node.child_value();
        if(pugi::xml_node tmp_node=channel.child("pubDate"))
        {
            struct_channel.pubDate=timestrings_to_time_t(tmp_node.child_value());
        }
        else
        {
            struct_channel.pubDate=time(NULL);
        }
        if(pugi::xml_node tmp_node=channel.child("image"))
        {
            if(pugi::xml_node tmp_node2=tmp_node.child("url"))struct_channel.img.url=tmp_node2.child_value();
            if(pugi::xml_node tmp_node2=tmp_node.child("title"))struct_channel.img.titel=tmp_node2.child_value();
            if(pugi::xml_node tmp_node2=tmp_node.child("link"))struct_channel.img.link=tmp_node2.child_value();
        }

        Poco::Hash<std::string> myhash;
        for(pugi::xml_node item=channel.child("item"); item; item=item.next_sibling("item"))
        {
            key_pair kp;
            kp = key_pair();
            CL_newsitem ni;
            ni=CL_newsitem();
            if(pugi::xml_node tmp_node=item.child("guid"))kp.guid=myhash(tmp_node.value());
            if(pugi::xml_node tmp_node=item.child("title"))ni.title=tmp_node.child_value();
            if(pugi::xml_node tmp_node=item.child("description"))
                ni.description=strip_from_html(tmp_node.child_value());
            if(ni.description==""&&ni.title=="")continue; /* no valid news item according to RSS 2.0 spec */
            if(kp.guid==0) kp.guid=ni.description==""?myhash(ni.title):myhash(ni.description);
            news_hashes.insert(kp.guid);
            if(!(last_news_hash.find(kp.guid)==last_news_hash.end()))continue; /*news already got in last parse */
            zaehler++;
            if(pugi::xml_node tmp_node=item.child("pubDate"))
            {
                ni.pubDate=kp.t=timestrings_to_time_t(tmp_node.child_value());
            }
            else
            {
                kp.t=struct_channel.pubDate==0?time(NULL):struct_channel.pubDate;
            }
            if(pugi::xml_node tmp_node=item.child("author"))ni.author=tmp_node.child_value();
            if(pugi::xml_node tmp_node=item.child("link"))ni.link=tmp_node.child_value();
            map[kp].channel=struct_channel;
            map[kp].newsitem=ni;
        }
    }
    last_news_hash=news_hashes;
    return zaehler;
}

int CL_News_pool::CL_RSS_Quelle::parse_atom(newsmap& map, pugi::xml_document& atom_doc,
        pugi::xml_node& feed)
{
    std::set<std::size_t> news_hashes;
    int zaehler = 0;
    CL_channel struct_channel;
    /*
            struct_channel.image.url;
            struct_channel.image.titel;
            struct_channel.image.link;*/
    std::string feed_author;
    if(pugi::xml_node tmp_node=feed.child("title"))struct_channel.titel=tmp_node.child_value();
    if(pugi::xml_node tmp_node=feed.child("id"))struct_channel.url=tmp_node.child_value();
    if(pugi::xml_node tmp_node=feed.child("author"))
    {
        if(pugi::xml_node tmp_node2=tmp_node.child("name"))
            feed_author=tmp_node2.child_value();
    }
    if(pugi::xml_node tmp_node=feed.child("rights"))struct_channel.copyright=tmp_node.child_value();
    if(pugi::xml_node tmp_node=feed.child("updated"))
    {
        struct_channel.pubDate=timestrings_to_time_t(tmp_node.child_value());
    }
    else
    {
        struct_channel.pubDate=time(NULL);
    }
    if(struct_channel.url.length())
    {
//        if(pugi::xml_node tmp_node=struct_channel.child("logo"))
//        {
//            struct_channel.img.url=struct_channel.url+tmp_node.child_value();
//        }
//        else if(pugi::xml_node tmp_node2=struct_channel.child("icon"))
//        {
//            struct_channel.img.url=struct_channel.url+tmp_node2.child_value();
//        }
    }
    CL_newsitem ni;
    key_pair kp;
    for(pugi::xml_node item=feed.child("entry"); item; item=item.next_sibling("entry"))
    {
        ni.clear();
        handle_atom_item(ni,item);
        if(ni.description == "" && ni.title == "") continue; //no use of an empty news
        if(ni.author=="") ni.author=feed_author;
        kp.clear();
        kp.guid=(ni.description=="")?myhash(ni.title):myhash(ni.description);
        news_hashes.insert(kp.guid);
        if(!(last_news_hash.find(kp.guid)==last_news_hash.end()))continue; /*news already got in last parse */
        zaehler++;
        kp.t=ni.pubDate?ni.pubDate:struct_channel.pubDate;
        if(kp.t==0) kp.t=time(NULL);
        map[kp].channel=struct_channel;
        map[kp].newsitem=ni;
    }

    last_news_hash=news_hashes;
    return zaehler;
}


void CL_News_pool::CL_RSS_Quelle::handle_atom_item(CL_newsitem& ni,pugi::xml_node& item)
{
    ni.description=search_atom_item_for_description(item);
    ni.title=search_atom_item_for_title(item);
    ni.author=search_atom_item_for_author(item);
    ni.pubDate=search_atom_item_for_pubDate(item);
    ni.link=search_atom_item_for_link(item);
};

std::string CL_News_pool::CL_RSS_Quelle::search_atom_item_for_description(pugi::xml_node& item)
{
    pugi::xml_node content=item.find_child_by_attribute("summary","type","text");
    if(content)
    {
#warning TODO (markus#1#): Maybe unescaping of the text is necessary

        return content.child_value();
    }
    content=item.find_child_by_attribute("summary","type","html");
    if(content)
    {
        return strip_from_html(content.child_value());
    }
    content=item.find_child_by_attribute("content","type","text");
    if(content)
    {
#warning TODO (markus#1#): Maybe unescaping of the text is necessary

        return content.child_value();
    }
    content=item.find_child_by_attribute("content","type","html");
    if(content)
    {
        return strip_from_html(content.child_value());
    }
    return "";
}

std::string CL_News_pool::CL_RSS_Quelle::search_atom_item_for_title(pugi::xml_node& item)
{
    pugi::xml_node title=item.child("title");
    if(title)
    {
#warning TODO (markus#1#): Maybe unescaping of the text is necessary

        return title.child_value();
    }
    else
    {
        return "";
    }
}

std::string CL_News_pool::CL_RSS_Quelle::search_atom_item_for_link(pugi::xml_node& item)
{
    pugi::xml_node link=item.child("link");
    if(link)
    {
#warning TODO (markus#1#): Maybe unescaping of the text is necessary
        pugi::xml_attribute ref=link.attribute("href");
        if(ref)
        {
            return ref.value();
        }
    }
    return "";
}

std::string CL_News_pool::CL_RSS_Quelle::search_atom_item_for_author(pugi::xml_node& item)
{
    pugi::xml_node author=item.child("author");
    if(author)
    {
#warning TODO (markus#1#): Maybe unescaping of the text is necessary
        pugi::xml_node author_name=author.child("name");
        if(author_name)
        {
            return author_name.child_value();
        }
    }
    author=item.child("contributor");
    if(author)
    {
#warning TODO (markus#1#): Maybe unescaping of the text is necessary
        pugi::xml_node author_name=author.child("name");
        if(author_name)
        {
            return author_name.child_value();
        }
    }
    return "";
}

time_t CL_News_pool::CL_RSS_Quelle::search_atom_item_for_pubDate(pugi::xml_node& item)
{
    pugi::xml_node updated=item.child("updated");
    if(updated)
    {
        std::string times=updated.child_value();
        return timestrings_to_time_t(times);
    }
    updated=item.child("published");
    if(updated)
    {
        std::string times=updated.child_value();
        return timestrings_to_time_t(times);
    }
    return time(NULL);
}

